﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the Microsoft Public License (Ms-PL).
// See accompanying file License.txt or copy at http://mews.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Mews.Net
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.IO;

    /// <summary>Represents a client connection to a server.</summary>
    /// <typeparam name="TClient">The most-derived class implementing this interface.</typeparam>
    /// <threadsafety static="true" instance="false"/>
    public interface IClient<TClient> : IDisposable where TClient : IClient<TClient>
    {
        /// <summary>Enqueues <paramref name="command"/> to the internal command queue.</summary>
        /// <exception cref="ObjectDisposedException"><see cref="IDisposable.Dispose"/> has been called.</exception>
        void EnqueueCommand(ICommand<TClient> command);

        /// <summary>Dequeues an unspecified number of the oldest items from the command queue, sends them to the
        /// server and adds them to the internal command pipeline. Then removes the oldest item from the command
        /// pipeline, receives the associated response from the server and returns an object representing the response.
        /// </summary>
        /// <remarks>
        /// <para>Items in the command queue are only sent to the server if all items in the command pipeline are
        /// pipelinable.</para>
        /// </remarks>
        /// <exception cref="ClientBaseException">The response code received from the server indicates a known error
        /// condition, see the <see cref="ICommand{T}.ThrowOnError"/> implementation for information on which
        /// <see cref="ClientBaseException"/> subtype is thrown for a given response code.</exception>
        /// <exception cref="InvalidOperationException"><see cref="PendingCommandsCount"/> equals <c>0</c>.</exception>
        /// <exception cref="IOException">A general I/O error occurred, see <see cref="Exception.InnerException"/>
        /// for more information.</exception>
        /// <exception cref="ObjectDisposedException"><see cref="IDisposable.Dispose"/> has been called.</exception>
        /// <exception cref="UnexpectedResponseException">The response received from the server was neither led by a
        /// response code indicating a known error (see <see cref="ICommand{T}.ThrowOnError"/> implementation) nor was
        /// it equal to one of the codes in <paramref name="successResponseCodes"/>.</exception>
        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method has side-effects.")]
        IResponse GetResponse();

        /// <summary>Gets the sum of the length of the command queue and the command pipeline.</summary>
        int PendingCommandsCount { get; }
    }
}
